/*	$Id: cookietest.c 983 2009-09-01 02:45:42Z phrakt $	*/
/*
 * Copyright (c) 2008 Jean-Francois Brousseau <phrakt@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/types.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <canopy/log.h>

#include <http/http.h>
#include <http/cookie.h>

#include "test.h"



struct cookie_test {
	char      *ck_string;
	char      *ck_name;
	char      *ck_val;
	char      *ck_domain;
	char      *ck_path;
	time_t     ck_expiry;
	int        ck_secure;
};




struct cookie_test tests[] = {
	{
		"sessionid=03ffedb48861fd7e",
		"sessionid", "03ffedb48861fd7e", NULL, NULL, 0, 0,
	},
	{
		"sessionid=03ffedb48861fd7e; domain=.example.com",
		"sessionid", "03ffedb48861fd7e", ".example.com", NULL, 0, 0,
	},
	{
		"sid=03ffedb48861fd7e; path=/cgi-bin",
		"sid", "03ffedb48861fd7e", NULL, "/cgi-bin", 0, 0,
	},
	{
		"clientid=\"WILE_E_COYOTE\"; path=\"/acme\"",
		"clientid", "WILE_E_COYOTE", NULL, "/acme", 0, 0,
	},
	{
		"grepfoobar_data=a%3A2%3A%7Bs%3A11%3A%18autologinid%18%3Bs%3A32%3A%187da649f9525a8001deeb56374%18%3Bs%3A6%3A%18userid%18%3A2403%7D; expires=Sat, 25-Apr-2009 15:48:44 GMT; path=/",
		"grepfoobar_data", "a%3A2%3A%7Bs%3A11%3A%18autologinid%18%3Bs%3A32%3A%187da649f9525a8001deeb56374%18%3Bs%3A6%3A%18userid%18%3A2403%7D", NULL, "/", 0, 0,
	},
	{
		"grepfoobar_sid=bf18e57e8daed3448a6108f0ff067c1a6a; path=/",
		"grepfoobar_sid", "bf18e57e8daed3448a6108f0ff067c1a6a", NULL,
		"/", 0, 0,
	},
	{
		"phpbb3_3bcoa_u=9; expires=Sat, 25-Apr-2009 15:40:02 GMT; path=/; domain=example.com; HttpOnly",
		"phpbb3_3bcoa_u", "9", "example.com", "/", 0, 0
	},
	{
		"phpbb3_3bcoa_sid=08a3e5f435359c0ac0c43ca8d9f5a; expires=Sat, 25-Apr-2009 15:40:02 GMT; path=/; domain=example.com; HttpOnly",
		"phpbb3_3bcoa_sid", "08a3e5f435359c0ac0c43ca8d9f5a",
		"example.com", "/", 0, 0,
	},
	{
		"bbsessionhash=58b8cbff4cae4a9846e323675138908; path=/; HttpOnly",
		"bbsessionhash", "58b8cbff4cae4a9846e323675138908", NULL, "/",
		0, 0,
	},
	{
		"OAID=e86c68fd693a675aadd68ec83449602; expires=Sat, 25 Apr 2009 15:40:08 GMT; path=/",
		"OAID", "e86c68fd693a675aadd68ec83449602", NULL, "/", 0, 0,
	},
	{
		"OAVARS[a68c3e2f]=3A%7Bs%3A8%3A%18bid%18%3Bs%3A3%3A%18165%18%3Bs%3A6%3A%18zoneid%18%3Bs%3A2%3A%1813%18%3Bs%3A6%3A%18oadest%18%3Bs%3A0%3A%18%18%3B%7D; path=/",
		"OAVARS[a68c3e2f]", "3A%7Bs%3A8%3A%18bid%18%3Bs%3A3%3A%18165%18%3Bs%3A6%3A%18zoneid%18%3Bs%3A2%3A%1813%18%3Bs%3A6%3A%18oadest%18%3Bs%3A0%3A%18%18%3B%7D", NULL, "/", 0, 0,
	},
	{
		"bblastvisit=1204679325; expires=Sat, 25 Apr 2009 15:40:09 GMT; path=/",
		"bblastvisit", "1204679325", NULL, "/", 0, 0,
	},
	{
		"bblastactivity=0; expires=Sat, 25 Apr 2009 15:40:09 GMT; path=/",
		"bblastactivity", "0", NULL, "/", 0, 0
	},
	{
		"rdk2094-5738_1032=0; path=/; Max-Age=0; expires=Wednesday, 09-Nov-99 23:12:40 GMT",
		"rdk2094-5738_1032", "0", NULL, "/", 0, 0,
	},
	{
		"csi=46396.js^4^1209134042^1209138033&46392.js^3^1209073511^1209137208&46397.js^4^1209134045^1209135753&46393.js^4^1209073510^1209134706&46394.js^1^1209073516^1209073516&46395.js^1^1209073507^1209073507&26913.js^1^1208405830^1208405830; expires=Wed, 18-Oct-2008 15:40:33 GMT; max-age=1184690033; path=/; domain=.rubycon.com;",
		"csi", "", ".rubycon.com", "/", 0, 0
	},
	{
		"eyeblaster=BWVal=14&BWDate=39563.440347&debuglevel=&FLV=9&RES=16&WMPV=9; expires=Thu, 31-Dec-2037 18:00:00 GMT; domain=bs.swerving-deer.com; path=/",
		"eyeblaster", "", "bs.swerving-deer.com", "/", 0, 0
	},
	{
		"A2=2.3o4yD6050B0000820wcW3ci34DPh02.Q0000820wd92+be4v5a04H10000o61wcM2Tkg4vvp04H10000g210cN3dA44Ffd04H10000b2MIdd2Rwg4r9604+e0000820wcB2.2J4Ffs050B0000M62wdd2RpY4qfB05f90000820wcy; expires=Thu, 31-Dec-2037 18:00:00 GMT; domain=.serving-sys.com; path=/",
		"A2", "", NULL, NULL, 0, 0
	},
	{
		"fl_inst=; expires=Mon, 01-Mar-2004 00:00:00 GMT",
		"fl_inst", "", NULL, NULL, 0, 0
	},
	{
		"uid=uid=a1a0cd68-e8b6-11dc-b6cc-0050455f111c&_hmacv=1&_salt=1287912036&_keyid=k1&_hmac=d09d5e9dbd408b35ae1855b285ae594618db2d28; expires=Sun, 25-May-2008 15:40:39 GMT",
		"uid", "uid=a1a0cd68-e8b6-11dc-b6cc-0050455f111c&_hmacv=1&_salt=1287912036&_keyid=k1&_hmac=d09d5e9dbd408b35ae1855b285ae594618db2d28", NULL, NULL, 0, 0
	},
	{
		"pv1=\"b!!!!.!!%Y]!!!Zt!!LSU!#+<P!!DPR!!mT-!?5%!*)6L<![:Z-!!Pq#!!U6/~~~~:/Dr:/ETN!!*i8!!!Fa!!%a!=As!$S`R_?!Zd<(!!(9/!!K76~~~9r.d2~M.jTN!!!9_!!-!!oi[!!>VS!,(%!*)R_?!Zd<(!!(9/!~~~~9r.gS9r:djTN!:!)tUD!!k!_Kd!!7xjO,!?%(6:#=A.3!!E[IC/!!ET/!!E4,~~~~9u4<N!!$P8!)tUD!!CLk!!glc!!:`u!!H<*!?5%!(Kv09!wVd.!!Qo)!!H+q!!Hy^~~~~~9yxjT~~!!'CaOo!!GUh!!!!$!?5%!)e6U>!ZmB)!!YI=!!YIJ~~)qp(~~!!%ly!!-Et!!F1d!#0G,%!%n/M2![:Z-!!YH^!!YHh~~~:*ReD:.fON~!!'Gh-!F1d!#0G,!!GU7!!$!?5%!%n/M2![!YH^!!YHh~~:*ReD~~!!!!!Zt!!NE4!#?$]!!E9U!!!!$!?5%!*)-F/81]:<rI#~!$!?5%!!?mK)!ZZN/!!O3V!!Yc-~~~~~~:/_?4~~\"; path=/; expires=Sun, 25-Apr-2010 15:40:39 GMT",
		"pv1", "", NULL, "/", 0, 0
	},
	{
		"vh=\"b\"; path=/; expires=Mon, 01-Mar-2004 00:00:00 GMT",
		"vh", "b", NULL, "/", 0, 0
	},
	{
		"ANON_ID=bSm0hURqMq3rexRDUvskfvTZbPTVruUcFXVW94HSdJ5RWMfydUpUGT69tSBwMrMBNqWP0CcEESpbMMGvs1Um2pMl2txWWFPGfaQFWErDbXk7cJNXDmBR9PcPp6nbqJDFa3xMTAAIS28trfWXU7hQVCanHqCWFJN3d3N57Zb8Is7ChqPUvq3rh4upPy1Q3GXaBPVrraUarXVjBlUd; path=/; domain=.spinalfunction.com; expires=Sat, 25-Apr-2009 15:40:39 GMT;",
		"ANON_ID", "", ".spinalfunction.com", "/", 0, 0
	},
	{
		"vuday1=-Q-=9l<M+N</qq9^@Q; expires=Sat, 26-Apr-2008 00:00:00 GMT",
		"vuday", "-Q-=9al<M+N<h/qq9^@Q", NULL, NULL, 0, 0
	},
	{
		"S=ftail=c9ei_svj62m78b2f7Hpgig:ftail_yj=12JufH-eLbMJnC1bi_x_2w:ftproxy=FflNOSoViC8:ftproxy_yj=DbHAHb2XjJM:ftproxy_yj_sub=QYDGm4sa7Gw; Path=/tail",
		"", "", NULL, "/tail", 0, 0
	},
};


int
test_parse_cookie(struct cookie_test *test)
{
	int ret;
	char buf[1024];
	const char *val;
	http_cookie_t *cookie;

	if ((cookie = http_cookie_parse(test->ck_string)) == NULL) {
		test_log("Parsing failed");
		return (TEST_FAIL);
	}

	val = http_cookie_getname(cookie);
	TEST_ASSERT_STRINGS_EQUAL("cookie name", test->ck_name, val);

	val = http_cookie_getdomain(cookie);
	TEST_ASSERT_STRINGS_EQUAL("cookie domain", test->ck_domain, val);

	val = http_cookie_getpath(cookie);
	TEST_ASSERT_STRINGS_EQUAL("cookie path", test->ck_path, val);

	return (TEST_OK);
}


int
test_format_cookie(struct cookie_test *test)
{
	int ret;
	char buf[1024], *val;
	http_cookie_t *cookie;

	if ((cookie = http_cookie_alloc()) == NULL)
		return (TEST_FAIL);

	if (http_cookie_setname(cookie, test->ck_name) == -1) {
		return (TEST_FAIL);
	}

	if (http_cookie_setval(cookie, test->ck_val) == -1) {
		return (TEST_FAIL);
	}

	if (http_cookie_setdomain(cookie, test->ck_domain) == -1) {
		return (TEST_FAIL);
	}

	if (http_cookie_setpath(cookie, test->ck_path) == -1) {
		return (TEST_FAIL);
	}

	if (http_cookie_setexpiry(cookie, test->ck_expiry) == -1) {
		return (TEST_FAIL);
	}

	if (http_cookie_setsecure(cookie, test->ck_secure) == -1) {
		return (TEST_FAIL);
	}

	ret = http_cookie_format(cookie, buf, sizeof(buf));
	if (ret == -1) {
		return (TEST_FAIL);
	}

	TEST_ASSERT_STRINGS_EQUAL("cookie", test->ck_string, buf);

	return (TEST_OK);
}


int
main(int argc, char **argv)
{
	int result;
	unsigned int i;

	http_init();
	test_init();

	for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) {
		test_start("test_parse_cookie");
		result = test_parse_cookie(&tests[i]);
		test_end(result);
	}

	for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) {
		test_start("test_format_cookie");
		result = test_format_cookie(&tests[i]);
		test_end(result);
	}

	test_cleanup();

	return (0);
}
